package main

import "fmt"

/**
18_模板模式
概念：定义一个操作中的算法的骨架，而将一些步骤延迟到子类中，使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
*/

type Downloader interface {
	Download(uri string)
}

// 具体实施
type implement interface {
	download()
	save()
}

// 模板
type template struct {
	implement
	uri string
}

func newTemplate(impl implement) *template {
	return &template{
		implement: impl,
		uri:       "",
	}
}

func (t *template) Download(uri string) {
	t.uri = uri
	fmt.Println("准备下载")
	t.implement.download()
	t.implement.save()
	fmt.Println("下载完毕")
}

func (t *template) save() {
	fmt.Println("默认保存")
}

// ===== 快播下载器=====
type QuickDownloader struct {
	*template
}

func NewQuickDownloader() *QuickDownloader {
	q := &QuickDownloader{}
	t := newTemplate(q)
	q.template = t
	return q
}

func (q *QuickDownloader) download() {
	fmt.Printf("正在使用快播下载器：%v\n", q.uri)
}

func (q *QuickDownloader) save() {
	fmt.Println("快播保存")
}

//===============FTP下载器================
type FtpDownloader struct {
	*template
}

func (hd *FtpDownloader) download() {
	fmt.Printf("正在通过HTTP下载：%v\n", hd.uri)
}
func (*FtpDownloader) save() {
	fmt.Println("HTTP保存")
}
func NewFtpDownloader() *FtpDownloader {
	downloader := &FtpDownloader{}
	template := newTemplate(downloader)
	downloader.template = template
	return downloader
}

func main() {
	quickDownloader := NewQuickDownloader()
	quickDownloader.Download("www.baidu.com/zip")

	ftpDownloader := NewFtpDownloader()
	ftpDownloader.Download("www.kuaibo.com/zxc")
}
